#include <stdio.h>
#include <openssl/evp.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <key> <data>\n", argv[0]);
        return 1;
    }

    unsigned char *key = (unsigned char *)argv[1];
    unsigned char *data = (unsigned char *)argv[2];
    size_t key_len = strlen((char *)key);
    size_t data_len = strlen((char *)data);

    // 创建和初始化EVP_MAC_CTX和EVP_MAC变量
    EVP_MAC_CTX *ctx;
    EVP_MAC *mac;
    OSSL_PARAM params[2];
    unsigned char *out;
    size_t out_len;

    // 设置算法类型
    mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
    ctx = EVP_MAC_CTX_new(mac);

    // 设置参数：摘要算法
    params[0] = OSSL_PARAM_construct_utf8_string("digest", "SM3", 0);
    params[1] = OSSL_PARAM_construct_end();

    if (!EVP_MAC_init(ctx, key, key_len, params)) {
        fprintf(stderr, "Failed to initialize HMAC\n");
        return 1;
    }

    if (!EVP_MAC_update(ctx, data, data_len)) {
        fprintf(stderr, "Failed to update HMAC\n");
        return 1;
    }

    // 计算HMAC长度
    EVP_MAC_final(ctx, NULL, &out_len, 0);
    out = malloc(out_len);

    if (!EVP_MAC_final(ctx, out, &out_len, out_len)) {
        fprintf(stderr, "Failed to finalize HMAC\n");
        return 1;
    }

    // 打印结果
    printf("HMAC: ");
    for (size_t i = 0; i < out_len; i++) {
        printf("%02x", out[i]);
    }
    printf("\n");

    // 清理资源
    EVP_MAC_CTX_free(ctx);
    EVP_MAC_free(mac);
    free(out);

    return 0;
}

